home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Communication / MMEdit / Source / jpegv3 / jwrjfif.c < prev    next >
C/C++ Source or Header  |  1993-01-12  |  11KB  |  461 lines

  1. /*
  2.  * jwrjfif.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains routines to write standard JPEG file headers/markers.
  9.  * The file format created is a raw JPEG data stream with (optionally) an
  10.  * APP0 marker per the JFIF spec.  This will handle baseline and
  11.  * JFIF-convention JPEG files, although there is currently no provision
  12.  * for inserting a thumbnail image in the JFIF header.
  13.  *
  14.  * These routines may need modification for non-Unix environments or
  15.  * specialized applications.  As they stand, they assume output to
  16.  * an ordinary stdio stream.  However, the changes to write to something
  17.  * else are localized in the macros appearing just below.
  18.  *
  19.  * These routines are invoked via the methods write_file_header,
  20.  * write_scan_header, write_jpeg_data, write_scan_trailer, and
  21.  * write_file_trailer.
  22.  */
  23.  
  24. #include "jinclude.h"
  25.  
  26. #ifdef JFIF_SUPPORTED
  27.  
  28. /* Write a single byte */
  29. #define emit_byte(cinfo,x)  NXPutc(cinfo->output_file, (x))
  30.  
  31. /* Write some bytes from a (char *) buffer */
  32. #define WRITE_BYTES(cinfo,dataptr,datacount)  \
  33.   { if (NXWrite(cinfo->output_file, dataptr, datacount) \
  34.     != (size_t) (datacount)) \
  35.       ERREXIT(cinfo->emethods, "Output file write error"); }
  36.  
  37. /* End of stdio-specific code. */
  38.  
  39.  
  40. typedef enum {            /* JPEG marker codes */
  41.   M_SOF0  = 0xc0,
  42.   M_SOF1  = 0xc1,
  43.   M_SOF2  = 0xc2,
  44.   M_SOF3  = 0xc3,
  45.   
  46.   M_SOF5  = 0xc5,
  47.   M_SOF6  = 0xc6,
  48.   M_SOF7  = 0xc7,
  49.   
  50.   M_JPG   = 0xc8,
  51.   M_SOF9  = 0xc9,
  52.   M_SOF10 = 0xca,
  53.   M_SOF11 = 0xcb,
  54.   
  55.   M_SOF13 = 0xcd,
  56.   M_SOF14 = 0xce,
  57.   M_SOF15 = 0xcf,
  58.   
  59.   M_DHT   = 0xc4,
  60.   
  61.   M_DAC   = 0xcc,
  62.   
  63.   M_RST0  = 0xd0,
  64.   M_RST1  = 0xd1,
  65.   M_RST2  = 0xd2,
  66.   M_RST3  = 0xd3,
  67.   M_RST4  = 0xd4,
  68.   M_RST5  = 0xd5,
  69.   M_RST6  = 0xd6,
  70.   M_RST7  = 0xd7,
  71.   
  72.   M_SOI   = 0xd8,
  73.   M_EOI   = 0xd9,
  74.   M_SOS   = 0xda,
  75.   M_DQT   = 0xdb,
  76.   M_DNL   = 0xdc,
  77.   M_DRI   = 0xdd,
  78.   M_DHP   = 0xde,
  79.   M_EXP   = 0xdf,
  80.   
  81.   M_APP0  = 0xe0,
  82.   M_APP15 = 0xef,
  83.   
  84.   M_JPG0  = 0xf0,
  85.   M_JPG13 = 0xfd,
  86.   M_COM   = 0xfe,
  87.   
  88.   M_TEM   = 0x01,
  89.   
  90.   M_ERROR = 0x100
  91. } JPEG_MARKER;
  92.  
  93.  
  94. LOCAL void
  95. emit_marker (compress_info_ptr cinfo, JPEG_MARKER mark)
  96. /* Emit a marker code */
  97. {
  98.   emit_byte(cinfo, 0xFF);
  99.   emit_byte(cinfo, mark);
  100. }
  101.  
  102.  
  103. LOCAL void
  104. emit_2bytes (compress_info_ptr cinfo, int value)
  105. /* Emit a 2-byte integer; these are always MSB first in JPEG files */
  106. {
  107.   emit_byte(cinfo, (value >> 8) & 0xFF);
  108.   emit_byte(cinfo, value & 0xFF);
  109. }
  110.  
  111.  
  112. LOCAL int
  113. emit_dqt (compress_info_ptr cinfo, int index)
  114. /* Emit a DQT marker */
  115. /* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
  116. {
  117.   QUANT_TBL_PTR data = cinfo->quant_tbl_ptrs[index];
  118.   int prec = 0;
  119.   int i;
  120.   
  121.   for (i = 0; i < DCTSIZE2; i++) {
  122.     if (data[i] > 255)
  123.       prec = 1;
  124.   }
  125.  
  126.   emit_marker(cinfo, M_DQT);
  127.   
  128.   emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
  129.   
  130.   emit_byte(cinfo, index + (prec<<4));
  131.   
  132.   for (i = 0; i < DCTSIZE2; i++) {
  133.     if (prec)
  134.       emit_byte(cinfo, data[i] >> 8);
  135.     emit_byte(cinfo, data[i] & 0xFF);
  136.   }
  137.  
  138.   return prec;
  139. }
  140.  
  141.  
  142. LOCAL void
  143. emit_dht (compress_info_ptr cinfo, int index, boolean is_ac)
  144. /* Emit a DHT marker */
  145. {
  146.   HUFF_TBL * htbl;
  147.   int length, i;
  148.   
  149.   if (is_ac) {
  150.     htbl = cinfo->ac_huff_tbl_ptrs[index];
  151.     index += 0x10;        /* output index has AC bit set */
  152.   } else {
  153.     htbl = cinfo->dc_huff_tbl_ptrs[index];
  154.   }
  155.  
  156.   if (htbl == NULL)
  157.     ERREXIT1(cinfo->emethods, "Huffman table 0x%02x was not defined", index);
  158.   
  159.   if (! htbl->sent_table) {
  160.     emit_marker(cinfo, M_DHT);
  161.     
  162.     length = 0;
  163.     for (i = 1; i <= 16; i++)
  164.       length += htbl->bits[i];
  165.     
  166.     emit_2bytes(cinfo, length + 2 + 1 + 16);
  167.     emit_byte(cinfo, index);
  168.     
  169.     for (i = 1; i <= 16; i++)
  170.       emit_byte(cinfo, htbl->bits[i]);
  171.     
  172.     for (i = 0; i < length; i++)
  173.       emit_byte(cinfo, htbl->huffval[i]);
  174.     
  175.     htbl->sent_table = TRUE;
  176.   }
  177. }
  178.  
  179.  
  180. LOCAL void
  181. emit_dac (compress_info_ptr cinfo)
  182. /* Emit a DAC marker */
  183. /* Since the useful info is so small, we want to emit all the tables in */
  184. /* one DAC marker.  Therefore this routine does its own scan of the table. */
  185. {
  186.   char dc_in_use[NUM_ARITH_TBLS];
  187.   char ac_in_use[NUM_ARITH_TBLS];
  188.   int length, i;
  189.   
  190.   for (i = 0; i < NUM_ARITH_TBLS; i++)
  191.     dc_in_use[i] = ac_in_use[i] = 0;
  192.   
  193.   for (i = 0; i < cinfo->num_components; i++) {
  194.     dc_in_use[cinfo->comp_info[i].dc_tbl_no] = 1;
  195.     ac_in_use[cinfo->comp_info[i].ac_tbl_no] = 1;
  196.   }
  197.   
  198.   length = 0;
  199.   for (i = 0; i < NUM_ARITH_TBLS; i++)
  200.     length += dc_in_use[i] + ac_in_use[i];
  201.   
  202.   emit_marker(cinfo, M_DAC);
  203.   
  204.   emit_2bytes(cinfo, length*2 + 2);
  205.   
  206.   for (i = 0; i < NUM_ARITH_TBLS; i++) {
  207.     if (dc_in_use[i]) {
  208.       emit_byte(cinfo, i);
  209.       emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
  210.     }
  211.     if (ac_in_use[i]) {
  212.       emit_byte(cinfo, i + 0x10);
  213.       emit_byte(cinfo, cinfo->arith_ac_K[i]);
  214.     }
  215.   }
  216. }
  217.  
  218.  
  219. LOCAL void
  220. emit_dri (compress_info_ptr cinfo)
  221. /* Emit a DRI marker */
  222. {
  223.   emit_marker(cinfo, M_DRI);
  224.   
  225.   emit_2bytes(cinfo, 4);    /* fixed length */
  226.  
  227.   emit_2bytes(cinfo, (int) cinfo->restart_interval);
  228. }
  229.  
  230.  
  231. LOCAL void
  232. emit_sof (compress_info_ptr cinfo, JPEG_MARKER code)
  233. /* Emit a SOF marker */
  234. {
  235.   int i;
  236.   
  237.   emit_marker(cinfo, code);
  238.   
  239.   emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
  240.  
  241.   if (cinfo->image_height > 65535L || cinfo->image_width > 65535L)
  242.     ERREXIT(cinfo->emethods, "Maximum image dimension for JFIF is 65535 pixels");
  243.  
  244.   emit_byte(cinfo, cinfo->data_precision);
  245.   emit_2bytes(cinfo, (int) cinfo->image_height);
  246.   emit_2bytes(cinfo, (int) cinfo->image_width);
  247.  
  248.   emit_byte(cinfo, cinfo->num_components);
  249.  
  250.   for (i = 0; i < cinfo->num_components; i++) {
  251.     emit_byte(cinfo, cinfo->comp_info[i].component_id);
  252.     emit_byte(cinfo, (cinfo->comp_info[i].h_samp_factor << 4)
  253.              + cinfo->comp_info[i].v_samp_factor);
  254.     emit_byte(cinfo, cinfo->comp_info[i].quant_tbl_no);
  255.   }
  256. }
  257.  
  258.  
  259. LOCAL void
  260. emit_sos (compress_info_ptr cinfo)
  261. /* Emit a SOS marker */
  262. {
  263.   int i;
  264.   
  265.   emit_marker(cinfo, M_SOS);
  266.   
  267.   emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
  268.   
  269.   emit_byte(cinfo, cinfo->comps_in_scan);
  270.   
  271.   for (i = 0; i < cinfo->comps_in_scan; i++) {
  272.     emit_byte(cinfo, cinfo->cur_comp_info[i]->component_id);
  273.     emit_byte(cinfo, (cinfo->cur_comp_info[i]->dc_tbl_no << 4)
  274.              + cinfo->cur_comp_info[i]->ac_tbl_no);
  275.   }
  276.  
  277.   emit_byte(cinfo, 0);        /* Spectral selection start */
  278.   emit_byte(cinfo, DCTSIZE2-1);    /* Spectral selection end */
  279.   emit_byte(cinfo, 0);        /* Successive approximation */
  280. }
  281.  
  282.  
  283. LOCAL void
  284. emit_jfif_app0 (compress_info_ptr cinfo)
  285. /* Emit a JFIF-compliant APP0 marker */
  286. {
  287.   /*
  288.    * Length of APP0 block    (2 bytes)
  289.    * Block ID            (4 bytes - ASCII "JFIF")
  290.    * Zero byte            (1 byte to terminate the ID string)
  291.    * Version Major, Minor    (2 bytes - 0x01, 0x01)
  292.    * Units            (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
  293.    * Xdpu            (2 bytes - dots per unit horizontal)
  294.    * Ydpu            (2 bytes - dots per unit vertical)
  295.    * Thumbnail X size        (1 byte)
  296.    * Thumbnail Y size        (1 byte)
  297.    */
  298.   
  299.   emit_marker(cinfo, M_APP0);
  300.   
  301.   emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
  302.  
  303.   emit_byte(cinfo, 'J');    /* Identifier */
  304.   emit_byte(cinfo, 'F');
  305.   emit_byte(cinfo, 'I');
  306.   emit_byte(cinfo, 'F');
  307.   emit_byte(cinfo, 0);
  308.   emit_byte(cinfo, 1);        /* Major version */
  309.   emit_byte(cinfo, 1);        /* Minor version */
  310.   emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
  311.   emit_2bytes(cinfo, (int) cinfo->X_density);
  312.   emit_2bytes(cinfo, (int) cinfo->Y_density);
  313.   emit_byte(cinfo, 0);        /* No thumbnail image */
  314.   emit_byte(cinfo, 0);
  315. }
  316.  
  317.  
  318. /*
  319.  * Write the file header.
  320.  */
  321.  
  322.  
  323. METHODDEF void
  324. write_file_header (compress_info_ptr cinfo)
  325. {
  326.   char qt_in_use[NUM_QUANT_TBLS];
  327.   int i, prec;
  328.   boolean is_baseline;
  329.   
  330.   emit_marker(cinfo, M_SOI);    /* first the SOI */
  331.  
  332.   if (cinfo->write_JFIF_header)    /* next an optional JFIF APP0 */
  333.     emit_jfif_app0(cinfo);
  334.  
  335.   /* Emit DQT for each quantization table. */
  336.   /* Note that doing it here means we can't adjust the QTs on-the-fly. */
  337.   /* If we did want to do that, we'd have a problem with checking precision */
  338.   /* for the is_baseline determination. */
  339.  
  340.   for (i = 0; i < NUM_QUANT_TBLS; i++)
  341.     qt_in_use[i] = 0;
  342.  
  343.   for (i = 0; i < cinfo->num_components; i++)
  344.     qt_in_use[cinfo->comp_info[i].quant_tbl_no] = 1;
  345.  
  346.   prec = 0;
  347.   for (i = 0; i < NUM_QUANT_TBLS; i++) {
  348.     if (qt_in_use[i])
  349.       prec += emit_dqt(cinfo, i);
  350.   }
  351.   /* now prec is nonzero iff there are any 16-bit quant tables. */
  352.  
  353.   if (cinfo->restart_interval)
  354.     emit_dri(cinfo);
  355.  
  356.   /* Check for a non-baseline specification. */
  357.   /* Note we assume that Huffman table numbers won't be changed later. */
  358.   is_baseline = TRUE;
  359.   if (cinfo->arith_code || (cinfo->data_precision != 8))
  360.     is_baseline = FALSE;
  361.   for (i = 0; i < cinfo->num_components; i++) {
  362.     if (cinfo->comp_info[i].dc_tbl_no > 1 || cinfo->comp_info[i].ac_tbl_no > 1)
  363.       is_baseline = FALSE;
  364.   }
  365.   if (prec && is_baseline) {
  366.     is_baseline = FALSE;
  367.     /* If it's baseline except for quantizer size, warn the user */
  368.     TRACEMS(cinfo->emethods, 0,
  369.         "Caution: quantization tables are too coarse for baseline JPEG");
  370.   }
  371.  
  372.  
  373.   /* Emit the proper SOF marker */
  374.   if (cinfo->arith_code)
  375.     emit_sof(cinfo, M_SOF9);    /* SOF code for arithmetic coding */
  376.   else if (is_baseline)
  377.     emit_sof(cinfo, M_SOF0);    /* SOF code for baseline implementation */
  378.   else
  379.     emit_sof(cinfo, M_SOF1);    /* SOF code for non-baseline Huffman file */
  380. }
  381.  
  382.  
  383. /*
  384.  * Write the start of a scan (everything through the SOS marker).
  385.  */
  386.  
  387. METHODDEF void
  388. write_scan_header (compress_info_ptr cinfo)
  389. {
  390.   int i;
  391.  
  392.   if (cinfo->arith_code) {
  393.     /* Emit arith conditioning info.  We will have some duplication
  394.      * if the file has multiple scans, but it's so small it's hardly
  395.      * worth worrying about.
  396.      */
  397.     emit_dac(cinfo);
  398.   } else {
  399.     /* Emit Huffman tables.  Note that emit_dht takes care of
  400.      * suppressing duplicate tables.
  401.      */
  402.     for (i = 0; i < cinfo->comps_in_scan; i++) {
  403.       emit_dht(cinfo, cinfo->cur_comp_info[i]->dc_tbl_no, FALSE);
  404.       emit_dht(cinfo, cinfo->cur_comp_info[i]->ac_tbl_no, TRUE);
  405.     }
  406.   }
  407.  
  408.   emit_sos(cinfo);
  409. }
  410.  
  411.  
  412. /*
  413.  * Write some bytes of compressed data within a scan.
  414.  */
  415.  
  416. METHODDEF void
  417. write_jpeg_data (compress_info_ptr cinfo, char *dataptr, int datacount)
  418. {
  419.   WRITE_BYTES(cinfo, dataptr, datacount);
  420. }
  421.  
  422.  
  423. /*
  424.  * Finish up after a compressed scan (series of write_jpeg_data calls).
  425.  */
  426.  
  427. METHODDEF void
  428. write_scan_trailer (compress_info_ptr cinfo)
  429. {
  430.   /* no work needed in this format */
  431. }
  432.  
  433.  
  434. /*
  435.  * Finish up at the end of the file.
  436.  */
  437.  
  438. METHODDEF void
  439. write_file_trailer (compress_info_ptr cinfo)
  440. {
  441.   emit_marker(cinfo, M_EOI);
  442. }
  443.  
  444.  
  445. /*
  446.  * The method selection routine for standard JPEG header writing.
  447.  * This should be called from c_ui_method_selection if appropriate.
  448.  */
  449.  
  450. GLOBAL void
  451. jselwjfif (compress_info_ptr cinfo)
  452. {
  453.   cinfo->methods->write_file_header = write_file_header;
  454.   cinfo->methods->write_scan_header = write_scan_header;
  455.   cinfo->methods->write_jpeg_data = write_jpeg_data;
  456.   cinfo->methods->write_scan_trailer = write_scan_trailer;
  457.   cinfo->methods->write_file_trailer = write_file_trailer;
  458. }
  459.  
  460. #endif /* JFIF_SUPPORTED */
  461.